package cn.biplam.common.wrapper;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;

import cn.biplam.common.tools.TOOLS;

/**
 * 功能	日期操作类
 */
public class Date {

	private Calendar cal;
	private java.util.Date date;
	public static final String longPattern="yyyy-MM-dd HH:mm:ss";
	public static final String shortPattern="yyyy-MM-dd";
	
	private final int Count=10;
	private final int Year=0;
	private final int Monty=1;
	private final int Day=2;
	private final int DayOfMonth=3;
	private final int YearMonth=4;
	private final int YearMonthDay=5;
	
	int[] fields; 

	/**
	 * 构造函数，新建一个日期对象
	 */
	public Date(){
		this.date=new java.util.Date();
		this.init();
	}

	/**
	 * 构造方法 传入java.util.Date初始化
	 * @param date
	 */
	public Date(java.util.Date date){
		this.date=date;
		this.init();
	}

	/**
	 * 传入时间字符串初始化
	 * @param sDate		yyyy-MM-dd HH:mm:ss
	 * @throws ErrorMessage
	 */
	public Date(String sDate) throws ErrorMessage{
		this(sDate,"yyyy-MM-dd HH:mm:ss");
	}

	/**
	 * 传入时间字符串和格式串初始化
	 * @param sDate
	 * @param patten
	 * @throws ErrorMessage
	 */
	public Date(String sDate,String patten) throws ErrorMessage{
		try {
			SimpleDateFormat df = new SimpleDateFormat(patten);
			this.date = df.parse(sDate);
		} catch (ParseException e) {
			throw new ErrorMessage(e);
		}
		this.init();
	}
	
	private void init(){
		cal=Calendar.getInstance();
		cal.setTime(date);
		String dt=this.getDateTime();
		this.fields= new int[Count];
		this.fields[Year]=Integer.valueOf(dt.substring(0,4));
		this.fields[Monty]=Integer.valueOf(dt.substring(5,7));
		this.fields[Day]=Integer.valueOf(dt.substring(8,10));
	}

	/**
	 * 功能 按照指定格式获取日期字符串 
	 * @param sPattern 日期格式
	 * @return 指定格式日期
	 */
	public String getDateTime(String sPattern){

		/** 格式化日期 */
		SimpleDateFormat df=null;
		String returnValue="";

		if(date!=null){
			df=new SimpleDateFormat(sPattern);
			returnValue=df.format(date);
		}
		return returnValue;
	}

	/**
	 * 返回指定格式的日期字符串
	 * @param pattern	格式掩码
	 * @return String
	 */
	public String get(String pattern){
		return TOOLS.formatDate(this.date, pattern);
	}

	/**
	 * 返回日期中的年份
	 * @return int
	 */
	public int getYear(){
		return this.fields[0];
	}

	public int getMonth(){
		return this.fields[1];
	}
	
	public int getDay(){
		return this.fields[2];
	}

	/**
	 * 获取系统默认格式日期字符串
	 * @return 日期字符串
	 */
	public String getDateTime(){
		return getDateTime(longPattern);
	}

	/**
	 * 功能 获取当前时间，以从历元（1970 年1 月1 日00:00:00 GMT）至现在所经过的 UTC 毫秒数形式
	 * @return 毫秒时间
	 */
	public long getMillis(){
		java.util.Calendar c = java.util.Calendar.getInstance(); 
		c.setTime(date);        
		return c.getTimeInMillis();   
	}


	/**
	 * 功能 将字符串转换成日期对象，假设字符串格式为系统指定格式
	 * @param sDate 日期字符串
	 * @return 日期对象
	 */
	public static Date convertStringtoDate(String sDate) throws ErrorMessage{
		return convertStringtoDate(longPattern,sDate);
	}

	/**
	 * 功能 将字符串按指定格式转换成日期对象
	 * @param sMask 日期格式
	 * @param sDate 日期字符串
	 * @return 返回日期对象
	 */
	public static Date convertStringtoDate(String sMask,String sDate) throws ErrorMessage{

		SimpleDateFormat df=null;
		Date dateTime=null;
		df =new SimpleDateFormat(sMask);

		try{
			/** 转换成日期对象 */
			dateTime=new Date(df.parse(sDate));
		}catch(ParseException pe){
			throw new ErrorMessage(pe,"DateValue: "+sDate+" is an unknow value!");
		}

		return dateTime;
	}

	/**
	 * 返回毫秒表示的时间
	 * @return
	 */
	public long getTime(){
		return this.date.getTime();
	}

	/**
	 * 功能 返回毫秒
	 * @param date 时间
	 * @return 毫秒
	 */
	public static long getMillis(Date date){
		java.util.Calendar c = java.util.Calendar.getInstance(); 
		c.setTime(date.date);        
		return c.getTimeInMillis();   
	}

	/**
	 * 功能 返回日期相差毫秒
	 * @param lStart 开始日期
	 * @param lEnd 结束日期
	 * @return 日期相差毫秒
	 */
	public static long diffMillis(Date lStart,Date lEnd){
		long millis=getMillis(lEnd)-(getMillis(lStart));
		if(millis<0){
			return 0;
		}else{
			return millis;
		}
	}

	/**
	 * 功能 返回日期相差天数
	 * @param lStart 开始日期
	 * @param lEnd 结束日期
	 * @return 日期相差毫秒
	 */
	public static int diffDate(Date lStart,Date lEnd){
		return (int)(diffMillis(lStart,lEnd))/(24*3600*1000);
	}
	
	/**
	 * 比较两个日期是否相等(精确到天)
	 * @param lStart
	 * @param lEnd
	 * @return boolean
	 */
	public static boolean equalDay(Date lStart,Date lEnd){
		return 	lStart.getYear() == lEnd.getYear() &&
				lStart.getMonth()==lEnd.getMonth() &&
				lStart.getDay() == lEnd.getDay();
	}

	/**
	 * 返回字符串表示的与系统当前时间的时间差 x天x小时x分x秒
	 * @return
	 */
	public String getDiffDate(){
		return this.getDiffDate(new Date());
	}

	/**
	 * 返回字符串表示的时间差 x天x小时x分x秒
	 * @param sDate		yyyy-MM-dd HH:mm:ss
	 * @return
	 * @throws ErrorMessage
	 */
	public String getDiffDate(String sDate) throws ErrorMessage{
		return this.getDiffDate(new Date(sDate));
	}

	/**
	 * 返回字符串表示的时间差 x天x小时x分x秒
	 * @param now	当前时间
	 * @return String
	 */
	public String getDiffDate(Date now){
		long df=now.getTime()-this.getTime();
		long day=df/(24*60*60*1000);
		long hour=(df/(60*60*1000)-day*24);
		long min=((df/(60*1000))-day*24*60-hour*60);
		long s=(df/1000-day*24*60*60-hour*60*60-min*60);
		StringBuilder sb = new StringBuilder();
		if(day>0){
			sb.append(day);
			sb.append("天");
		}
		if(hour>0){
			sb.append(hour);
			sb.append("小时");
		}
		if(min>0){
			sb.append(min);
			sb.append("分");
		}
		if(s>0){
			sb.append(s);
			sb.append("秒");
		}
		return sb.toString();
	}
	
	/**
	 * 返回两个日期之间相差的天数
	 * @param now 最新日期
	 * @return int
	 */
	public int getDiffDay(Date now){
		long df=now.getTime()-this.getTime();
		return (int) (df/(24*60*60*1000));
	}

	/**
	 * 功能 返回日期对象的字符串表达形式
	 * @return
	 */
	public String toString(){
		return getDateTime(longPattern);
	}

	public int getDayOfMonth() throws ErrorMessage {
		if(fields[this.DayOfMonth]==0){
			StringBuilder sb=new StringBuilder();
			sb.append(this.getYear());
			sb.append("-");
			sb.append(this.getMonth()+1);
			sb.append("-01");
			Date dt = new Date(TOOLS.formatDate(sb.toString()),Date.shortPattern);
			fields[this.DayOfMonth]=this.getDiffDay(dt);
		}
		return fields[this.DayOfMonth];
	}
	
	/**
	 * 返回 java.util.Date
	 * @return java.util.Date
	 */
	public java.util.Date getDate(){
		return this.date;
	}

	/**
	 * 数字天份转字符天分,补0
	 * @param day
	 * @return
	 */
	public static String getDay(int day){
		String sDay=String.valueOf(day);
		return day<10?"0"+sDay:sDay; 
	}

	/**
	 * 数字月份转字符月份,补0
	 * @param month
	 * @return
	 */
	public static String getMonth(int month){
		String sMonth=String.valueOf(month);
		return month<10?"0"+sMonth:sMonth;
	}
	
	/**
	 * 返回日期+年份的数字(200901);
	 * @return int
	 */
	public int getYearMonth(){
		if(this.fields[this.YearMonth]==0){
			this.fields[this.YearMonth]=this.getYear()*100+this.getMonth();
		}
		return this.fields[this.YearMonth];
	}
	
	/**
	 * 返回日期+年份+天的数字(20090101);
	 * @return int
	 */
	public int getYearMonthDay(){
		if(this.fields[this.YearMonthDay]==0){
			this.fields[this.YearMonthDay]=this.getYearMonth()*100+this.getDay();
		}
		return this.fields[this.YearMonthDay];
	}
}
